package de.slothsoft.wasbinich.swingclient.control;

import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JButton;

import de.slothsoft.wasbinich.core.database.Database;
import de.slothsoft.wasbinich.core.database.DatabaseException;
import de.slothsoft.wasbinich.core.database.LoginBean;
import de.slothsoft.wasbinich.swingclient.GlobalEventScopes;
import de.slothsoft.wasbinich.swingclient.WasBinIchSwingClient;
import de.slothsoft.wasbinich.swingclient.common.GlobalEvent;
import de.slothsoft.wasbinich.swingclient.common.GlobalEventHandler;
import de.slothsoft.wasbinich.swingclient.common.GlobalListener;
import de.slothsoft.wasbinich.swingclient.control.TitlePanel.ScreenSwitcher;
import de.slothsoft.wasbinich.swingclient.res.Messages;

public class MainPanel extends WasBinIchPanel implements ScreenSwitcher {

    private static final long serialVersionUID = -3997338132414346556L;

    public static final String SCREEN_TITLE = "SCREEN_TITLE";
    public static final String SCREEN_GAME = "SCREEN_GAME";
    public static final String SCREEN_GAME_RESULT = "SCREEN_GAME_RESULT";
    public static final String SCREEN_PICTURES = "SCREEN_PICTURES";
    public static final String SCREEN_PICTURE = "SCREEN_PICTURE";
    public static final String SCREEN_ABOUT = "SCREEN_ABOUT";

    private final Map<String, SwitchPanel> panels = new HashMap<>();
    private final TitlePanel titlePanel;
    private String currentPanelId;

    public MainPanel() {
	CardLayout layout = new CardLayout();
	setLayout(layout);
	this.titlePanel = new TitlePanel(this);
	add(this.titlePanel, SCREEN_TITLE);
	this.panels.put(SCREEN_TITLE, this.titlePanel);
	createChildScreens();
	switchScreen(SCREEN_TITLE);
	repaint();
    }

    private void createChildScreens() {
	JButton startButton = addScreen(SCREEN_GAME, Messages.getString("GamePanel.title"), new GamePanel(this));
	addScreen(SCREEN_PICTURES, Messages.getString("PicturePanel.title"), new PicturesPanel(this));
	addLogInAndOutButton();
	addScreen(SCREEN_ABOUT, Messages.getString("AboutPanel.title"), new AboutPanel(this));

	addScreenWithoutButton(SCREEN_PICTURE, new PicturePanel(this));
	addScreenWithoutButton(SCREEN_GAME_RESULT, new GameResultPanel(this));

	startButton.addActionListener(new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent e) {
		startGame();
	    }
	});
    }

    protected void startGame() {
	GamePanel questionPanel = (GamePanel) getPanels().get(SCREEN_GAME);
	questionPanel.startGame();
    }

    private void addLogInAndOutButton() {
	final JButton button = this.titlePanel.addButton(Messages.getString("MainPanel.logIn"), new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent e) {
		LoginBean loginBean = Database.getInstance().getLoginBean();
		if (loginBean.isLoggedIn()) {
		    loginBean.logOut();
		} else {
		    try {
			loginBean.getLoginToken();
		    } catch (DatabaseException e1) {
			WasBinIchSwingClient.handleException(e1);
		    }
		}
	    }
	});
	GlobalEventHandler.getGlobalInstance().register(GlobalEventScopes.LOG_IN, new GlobalListener() {

	    @Override
	    public void handleEvent(GlobalEvent event) {
		button.setText(MessageFormat.format(Messages.getString("MainPanel.logOut"), event.getData()));
	    }
	});
	GlobalEventHandler.getGlobalInstance().register(GlobalEventScopes.LOG_OUT, new GlobalListener() {

	    @Override
	    public void handleEvent(GlobalEvent event) {
		button.setText(Messages.getString("MainPanel.logIn"));
	    }
	});
    }

    private JButton addScreen(String id, String title, ChildPanel component) {
	JButton button = this.titlePanel.addScreen(id, title);
	add(component, id);
	this.panels.put(id, component);
	component.setTitle(title);
	return button;
    }

    private void addScreenWithoutButton(String id, ChildPanel component) {
	add(component, id);
	this.panels.put(id, component);
    }

    @Override
    public SwitchPanel switchScreen(String id) {
	if (this.currentPanelId != null) {
	    this.panels.get(this.currentPanelId).hidePanel();
	}
	((CardLayout) getLayout()).show(this, id);
	doLayout();
	this.panels.get(id).showPanel();
	if (SCREEN_TITLE.equals(id)) {
	    ((GamePanel) this.panels.get(SCREEN_GAME)).quietlyEndGame();
	}
	return this.panels.get(id);
    }

    protected Map<String, SwitchPanel> getPanels() {
	return this.panels;
    }
}
